/* Polyfill service v3.25.1
 * For detailed credits and licence information see https://github.com/financial-times/polyfill-service.
 *
 * UA detected: ie/86.0.0
 * Features requested: default
 *
 * - _mutation, License: CC0 (required by "DocumentFragment.prototype.append", "default", "DocumentFragment.prototype.prepend", "Element.prototype.after", "Element.prototype.append", "Element.prototype.before", "Element.prototype.prepend", "Element.prototype.replaceWith")
 * - DocumentFragment.prototype.append, License: CC0 (required by "default")
 * - DocumentFragment.prototype.prepend, License: CC0 (required by "default")
 * - Element.prototype.after, License: CC0 (required by "default")
 * - Element.prototype.append, License: CC0 (required by "default")
 * - Element.prototype.before, License: CC0 (required by "default")
 * - Element.prototype.matches, License: CC0 (required by "default", "Element.prototype.closest")
 * - Element.prototype.closest, License: CC0 (required by "default")
 * - Element.prototype.prepend, License: CC0 (required by "default")
 * - Element.prototype.replaceWith, License: CC0 (required by "default")
 * - URL, License: CC0 (required by "default") */

(function(undefined) {

// _mutation
    var _mutation = (function () { // eslint-disable-line no-unused-vars

        function isNode(object) {
            // DOM, Level2
            if (typeof Node === 'function') {
                return object instanceof Node;
            }
            // Older browsers, check if it looks like a Node instance)
            return object &&
                typeof object === "object" &&
                object.nodeName &&
                object.nodeType >= 1 &&
                object.nodeType <= 12;
        }

        // http://dom.spec.whatwg.org/#mutation-method-macro
        return function mutation(nodes) {
            if (nodes.length === 1) {
                return isNode(nodes[0]) ? nodes[0] : document.createTextNode(nodes[0] + '');
            }

            var fragment = document.createDocumentFragment();
            for (var i = 0; i < nodes.length; i++) {
                fragment.appendChild(isNode(nodes[i]) ? nodes[i] : document.createTextNode(nodes[i] + ''));

            }
            return fragment;
        };
    }());

// DocumentFragment.prototype.append
    DocumentFragment.prototype.append = function append() {
        this.appendChild(_mutation(arguments));
    };

// DocumentFragment.prototype.prepend
    DocumentFragment.prototype.prepend = function prepend() {
        this.insertBefore(_mutation(arguments), this.firstChild);
    };

// Element.prototype.after
    Document.prototype.after = Element.prototype.after = function after() {
        if (this.parentNode) {
            var args = Array.prototype.slice.call(arguments),
                viableNextSibling = this.nextSibling,
                idx = viableNextSibling ? args.indexOf(viableNextSibling) : -1;

            while (idx !== -1) {
                viableNextSibling = viableNextSibling.nextSibling;
                if (!viableNextSibling) {
                    break;
                }
                idx = args.indexOf(viableNextSibling);
            }

            this.parentNode.insertBefore(_mutation(arguments), viableNextSibling);
        }
    };

// Not all UAs support the Text constructor.  Polyfill on the Text constructor only where it exists
// TODO: Add a polyfill for the Text constructor, and make it a dependency of this polyfill.
    if ("Text" in this) {
        Text.prototype.after = Element.prototype.after;
    }

// Element.prototype.append
    Document.prototype.append = Element.prototype.append = function append() {
        this.appendChild(_mutation(arguments));
    };

// Element.prototype.before
    Document.prototype.before = Element.prototype.before = function before() {
        if (this.parentNode) {
            var args = Array.prototype.slice.call(arguments),
                viablePreviousSibling = this.previousSibling,
                idx = viablePreviousSibling ? args.indexOf(viablePreviousSibling) : -1;

            while (idx !== -1) {
                viablePreviousSibling = viablePreviousSibling.previousSibling;
                if (!viablePreviousSibling) {
                    break;
                }
                idx = args.indexOf(viablePreviousSibling);
            }

            this.parentNode.insertBefore(
                _mutation(arguments),
                viablePreviousSibling ? viablePreviousSibling.nextSibling : this.parentNode.firstChild
            );
        }
    };

// Not all UAs support the Text constructor.  Polyfill on the Text constructor only where it exists
// TODO: Add a polyfill for the Text constructor, and make it a dependency of this polyfill.
    if ("Text" in this) {
        Text.prototype.before = Element.prototype.before;
    }

// Element.prototype.matches
    Element.prototype.matches = Element.prototype.webkitMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.mozMatchesSelector || function matches(selector) {

        var element = this;
        var elements = (element.document || element.ownerDocument).querySelectorAll(selector);
        var index = 0;

        while (elements[index] && elements[index] !== element) {
            ++index;
        }

        return !!elements[index];
    };

// Element.prototype.closest
    Element.prototype.closest = function closest(selector) {
        var node = this;

        while (node) {
            if (node.matches(selector)) return node;
            else node = 'SVGElement' in window && node instanceof SVGElement ? node.parentNode : node.parentElement;
        }

        return null;
    };

// Element.prototype.prepend
    Document.prototype.prepend = Element.prototype.prepend = function prepend() {
        this.insertBefore(_mutation(arguments), this.firstChild);
    };

// Element.prototype.replaceWith
    Document.prototype.replaceWith = Element.prototype.replaceWith = function replaceWith() {
        if (this.parentNode) {
            this.parentNode.replaceChild(_mutation(arguments), this);
        }
    };

// Not all UAs support the Text constructor.  Polyfill on the Text constructor only where it exists
// TODO: Add a polyfill for the Text constructor, and make it a dependency of this polyfill.
    if ('Text' in this) {
        Text.prototype.replaceWith = Element.prototype.replaceWith;
    }

// URL
// URL Polyfill
// Draft specification: https://url.spec.whatwg.org

// Notes:
// - Primarily useful for parsing URLs and modifying query parameters
// - Should work in IE8+ and everything more modern, with es5.js polyfills

    (function (global) {
        'use strict';

        function isSequence(o) {
            if (!o) return false;
            if ('Symbol' in global && 'iterator' in global.Symbol &&
                typeof o[Symbol.iterator] === 'function') return true;
            if (Array.isArray(o)) return true;
            return false;
        }

        function toArray(iter) {
            return ('from' in Array) ? Array.from(iter) : Array.prototype.slice.call(iter);
        }

        (function() {

            // Browsers may have:
            // * No global URL object
            // * URL with static methods only - may have a dummy constructor
            // * URL with members except searchParams
            // * Full URL API support
            var origURL = global.URL;
            var nativeURL;
            try {
                if (origURL) {
                    nativeURL = new global.URL('http://example.com');
                    if ('searchParams' in nativeURL)
                        return;
                    if (!('href' in nativeURL))
                        nativeURL = undefined;
                }
            } catch (_) {}

            // NOTE: Doesn't do the encoding/decoding dance
            function urlencoded_serialize(pairs) {
                var output = '', first = true;
                pairs.forEach(function (pair) {
                    var name = encodeURIComponent(pair.name);
                    var value = encodeURIComponent(pair.value);
                    if (!first) output += '&';
                    output += name + '=' + value;
                    first = false;
                });
                return output.replace(/%20/g, '+');
            }

            // NOTE: Doesn't do the encoding/decoding dance
            function urlencoded_parse(input, isindex) {
                var sequences = input.split('&');
                if (isindex && sequences[0].indexOf('=') === -1)
                    sequences[0] = '=' + sequences[0];
                var pairs = [];
                sequences.forEach(function (bytes) {
                    if (bytes.length === 0) return;
                    var index = bytes.indexOf('=');
                    if (index !== -1) {
                        var name = bytes.substring(0, index);
                        var value = bytes.substring(index + 1);
                    } else {
                        name = bytes;
                        value = '';
                    }
                    name = name.replace(/\+/g, ' ');
                    value = value.replace(/\+/g, ' ');
                    pairs.push({ name: name, value: value });
                });
                var output = [];
                pairs.forEach(function (pair) {
                    output.push({
                        name: decodeURIComponent(pair.name),
                        value: decodeURIComponent(pair.value)
                    });
                });
                return output;
            }

            function URLUtils(url) {
                if (nativeURL)
                    return new origURL(url);
                var anchor = document.createElement('a');
                anchor.href = url;
                return anchor;
            }

            function URLSearchParams(init) {
                var $this = this;
                this._list = [];

                if (init === undefined || init === null) {
                    // no-op
                } else if (init instanceof URLSearchParams) {
                    // In ES6 init would be a sequence, but special case for ES5.
                    this._list = urlencoded_parse(String(init));
                } else if (typeof init === 'object' && isSequence(init)) {
                    toArray(init).forEach(function(e) {
                        if (!isSequence(e)) throw TypeError();
                        var nv = toArray(e);
                        if (nv.length !== 2) throw TypeError();
                        $this._list.push({name: String(nv[0]), value: String(nv[1])});
                    });
                } else if (typeof init === 'object' && init) {
                    Object.keys(init).forEach(function(key) {
                        $this._list.push({name: String(key), value: String(init[key])});
                    });
                } else {
                    init = String(init);
                    if (init.substring(0, 1) === '?')
                        init = init.substring(1);
                    this._list = urlencoded_parse(init);
                }

                this._url_object = null;
                this._setList = function (list) { if (!updating) $this._list = list; };

                var updating = false;
                this._update_steps = function() {
                    if (updating) return;
                    updating = true;

                    if (!$this._url_object) return;

                    // Partial workaround for IE issue with 'about:'
                    if ($this._url_object.protocol === 'about:' &&
                        $this._url_object.pathname.indexOf('?') !== -1) {
                        $this._url_object.pathname = $this._url_object.pathname.split('?')[0];
                    }

                    $this._url_object.search = urlencoded_serialize($this._list);

                    updating = false;
                };
            }


            Object.defineProperties(URLSearchParams.prototype, {
                append: {
                    value: function (name, value) {
                        this._list.push({ name: name, value: value });
                        this._update_steps();
                    }, writable: true, enumerable: true, configurable: true
                },

                'delete': {
                    value: function (name) {
                        for (var i = 0; i < this._list.length;) {
                            if (this._list[i].name === name)
                                this._list.splice(i, 1);
                            else
                                ++i;
                        }
                        this._update_steps();
                    }, writable: true, enumerable: true, configurable: true
                },

                get: {
                    value: function (name) {
                        for (var i = 0; i < this._list.length; ++i) {
                            if (this._list[i].name === name)
                                return this._list[i].value;
                        }
                        return null;
                    }, writable: true, enumerable: true, configurable: true
                },

                getAll: {
                    value: function (name) {
                        var result = [];
                        for (var i = 0; i < this._list.length; ++i) {
                            if (this._list[i].name === name)
                                result.push(this._list[i].value);
                        }
                        return result;
                    }, writable: true, enumerable: true, configurable: true
                },

                has: {
                    value: function (name) {
                        for (var i = 0; i < this._list.length; ++i) {
                            if (this._list[i].name === name)
                                return true;
                        }
                        return false;
                    }, writable: true, enumerable: true, configurable: true
                },

                set: {
                    value: function (name, value) {
                        var found = false;
                        for (var i = 0; i < this._list.length;) {
                            if (this._list[i].name === name) {
                                if (!found) {
                                    this._list[i].value = value;
                                    found = true;
                                    ++i;
                                } else {
                                    this._list.splice(i, 1);
                                }
                            } else {
                                ++i;
                            }
                        }

                        if (!found)
                            this._list.push({ name: name, value: value });

                        this._update_steps();
                    }, writable: true, enumerable: true, configurable: true
                },

                entries: {
                    value: function() { return new Iterator(this._list, 'key+value'); },
                    writable: true, enumerable: true, configurable: true
                },

                keys: {
                    value: function() { return new Iterator(this._list, 'key'); },
                    writable: true, enumerable: true, configurable: true
                },

                values: {
                    value: function() { return new Iterator(this._list, 'value'); },
                    writable: true, enumerable: true, configurable: true
                },

                forEach: {
                    value: function(callback) {
                        var thisArg = (arguments.length > 1) ? arguments[1] : undefined;
                        this._list.forEach(function(pair, index) {
                            callback.call(thisArg, pair.value, pair.name);
                        });

                    }, writable: true, enumerable: true, configurable: true
                },

                toString: {
                    value: function () {
                        return urlencoded_serialize(this._list);
                    }, writable: true, enumerable: false, configurable: true
                }
            });

            function Iterator(source, kind) {
                var index = 0;
                this['next'] = function() {
                    if (index >= source.length)
                        return {done: true, value: undefined};
                    var pair = source[index++];
                    return {done: false, value:
                            kind === 'key' ? pair.name :
                                kind === 'value' ? pair.value :
                                    [pair.name, pair.value]};
                };
            }

            if ('Symbol' in global && 'iterator' in global.Symbol) {
                Object.defineProperty(URLSearchParams.prototype, global.Symbol.iterator, {
                    value: URLSearchParams.prototype.entries,
                    writable: true, enumerable: true, configurable: true});
                Object.defineProperty(Iterator.prototype, global.Symbol.iterator, {
                    value: function() { return this; },
                    writable: true, enumerable: true, configurable: true});
            }

            function URL(url, base) {
                if (!(this instanceof global.URL))
                    throw new TypeError("Failed to construct 'URL': Please use the 'new' operator.");

                if (base) {
                    url = (function () {
                        if (nativeURL) return new origURL(url, base).href;
                        var iframe;
                        try {
                            var doc;
                            // Use another document/base tag/anchor for relative URL resolution, if possible
                            if (Object.prototype.toString.call(window.operamini) === "[object OperaMini]") {
                                iframe = document.createElement('iframe');
                                iframe.style.display = 'none';
                                document.documentElement.appendChild(iframe);
                                doc = iframe.contentWindow.document;
                            } else if (document.implementation && document.implementation.createHTMLDocument) {
                                doc = document.implementation.createHTMLDocument('');
                            } else if (document.implementation && document.implementation.createDocument) {
                                doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
                                doc.documentElement.appendChild(doc.createElement('head'));
                                doc.documentElement.appendChild(doc.createElement('body'));
                            } else if (window.ActiveXObject) {
                                doc = new window.ActiveXObject('htmlfile');
                                doc.write('<head><\/head><body><\/body>');
                                doc.close();
                            }

                            if (!doc) throw Error('base not supported');

                            var baseTag = doc.createElement('base');
                            baseTag.href = base;
                            doc.getElementsByTagName('head')[0].appendChild(baseTag);
                            var anchor = doc.createElement('a');
                            anchor.href = url;
                            return anchor.href;
                        } finally {
                            if (iframe)
                                iframe.parentNode.removeChild(iframe);
                        }
                    }());
                }

                // An inner object implementing URLUtils (either a native URL
                // object or an HTMLAnchorElement instance) is used to perform the
                // URL algorithms. With full ES5 getter/setter support, return a
                // regular object For IE8's limited getter/setter support, a
                // different HTMLAnchorElement is returned with properties
                // overridden

                var instance = URLUtils(url || '');

                // Detect for ES5 getter/setter support
                // (an Object.defineProperties polyfill that doesn't support getters/setters may throw)
                var ES5_GET_SET = (function() {
                    if (!('defineProperties' in Object)) return false;
                    try {
                        var obj = {};
                        Object.defineProperties(obj, { prop: { 'get': function () { return true; } } });
                        return obj.prop;
                    } catch (_) {
                        return false;
                    }
                })();

                var self = ES5_GET_SET ? this : document.createElement('a');



                var query_object = new URLSearchParams(
                    instance.search ? instance.search.substring(1) : null);
                query_object._url_object = self;

                Object.defineProperties(self, {
                    href: {
                        get: function () { return instance.href; },
                        set: function (v) { instance.href = v; tidy_instance(); update_steps(); },
                        enumerable: true, configurable: true
                    },
                    origin: {
                        get: function () {
                            if ('origin' in instance) return instance.origin;
                            return this.protocol + '//' + this.host;
                        },
                        enumerable: true, configurable: true
                    },
                    protocol: {
                        get: function () { return instance.protocol; },
                        set: function (v) { instance.protocol = v; },
                        enumerable: true, configurable: true
                    },
                    username: {
                        get: function () { return instance.username; },
                        set: function (v) { instance.username = v; },
                        enumerable: true, configurable: true
                    },
                    password: {
                        get: function () { return instance.password; },
                        set: function (v) { instance.password = v; },
                        enumerable: true, configurable: true
                    },
                    host: {
                        get: function () {
                            // IE returns default port in |host|
                            var re = {'http:': /:80$/, 'https:': /:443$/, 'ftp:': /:21$/}[instance.protocol];
                            return re ? instance.host.replace(re, '') : instance.host;
                        },
                        set: function (v) { instance.host = v; },
                        enumerable: true, configurable: true
                    },
                    hostname: {
                        get: function () { return instance.hostname; },
                        set: function (v) { instance.hostname = v; },
                        enumerable: true, configurable: true
                    },
                    port: {
                        get: function () { return instance.port; },
                        set: function (v) { instance.port = v; },
                        enumerable: true, configurable: true
                    },
                    pathname: {
                        get: function () {
                            // IE does not include leading '/' in |pathname|
                            if (instance.pathname.charAt(0) !== '/') return '/' + instance.pathname;
                            return instance.pathname;
                        },
                        set: function (v) { instance.pathname = v; },
                        enumerable: true, configurable: true
                    },
                    search: {
                        get: function () { return instance.search; },
                        set: function (v) {
                            if (instance.search === v) return;
                            instance.search = v; tidy_instance(); update_steps();
                        },
                        enumerable: true, configurable: true
                    },
                    searchParams: {
                        get: function () { return query_object; },
                        enumerable: true, configurable: true
                    },
                    hash: {
                        get: function () { return instance.hash; },
                        set: function (v) { instance.hash = v; tidy_instance(); },
                        enumerable: true, configurable: true
                    },
                    toString: {
                        value: function() { return instance.toString(); },
                        enumerable: false, configurable: true
                    },
                    valueOf: {
                        value: function() { return instance.valueOf(); },
                        enumerable: false, configurable: true
                    }
                });

                function tidy_instance() {
                    var href = instance.href.replace(/#$|\?$|\?(?=#)/g, '');
                    if (instance.href !== href)
                        instance.href = href;
                }

                function update_steps() {
                    query_object._setList(instance.search ? urlencoded_parse(instance.search.substring(1)) : []);
                    query_object._update_steps();
                };

                return self;
            }

            if (origURL) {
                for (var i in origURL) {
                    if (origURL.hasOwnProperty(i) && typeof origURL[i] === 'function')
                        URL[i] = origURL[i];
                }
            }

            global.URL = URL;
            global.URLSearchParams = URLSearchParams;
        }());

        // Patch native URLSearchParams constructor to handle sequences/records
        // if necessary.
        (function() {
            if (new global.URLSearchParams([['a', 1]]).get('a') === '1' &&
                new global.URLSearchParams({a: 1}).get('a') === '1')
                return;
            var orig = global.URLSearchParams;
            global.URLSearchParams = function(init) {
                if (init && typeof init === 'object' && isSequence(init)) {
                    var o = new orig();
                    toArray(init).forEach(function(e) {
                        if (!isSequence(e)) throw TypeError();
                        var nv = toArray(e);
                        if (nv.length !== 2) throw TypeError();
                        o.append(nv[0], nv[1]);
                    });
                    return o;
                } else if (init && typeof init === 'object') {
                    o = new orig();
                    Object.keys(init).forEach(function(key) {
                        o.set(key, init[key]);
                    });
                    return o;
                } else {
                    return new orig(init);
                }
            };
        }());

    }(self));
})
    .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});